<?php defined('SMIT_PATH') or die('Access Denied');
/**
 *	mysql.php - MySQL Driver for SmitBoard
 *	This is Smit Matterhorn - Build 24109
 *	
 *
 * @author		The SmitBoard Team & Community
 * @license		GNU GPL v3
 * @link		http://smitboard.sf.net
 * @since		Matterhorn
 */
 
class driverMysql extends dbMaster
{
	
	public $driver = 'MySQL';
	public $driver_version = '1.0 PF';
	public $driver_author = 'Matix';
	
	public $dependency = 'mysql';
	
	protected $l_delim = '`';
	protected $r_delim = '`';
	protected $l_delim_val = '\'';
	protected $r_delim_val = '\'';

	function connect($config = array())
	{
		if(count($config) == 0)
		{
			$config = $this->base->vars['root'];
		}
		$cmd = ($config['db_persist']) ? 'mysql_pconnect' : 'mysql_connect';
		$port = (is_int($config['db_port']) ? ':' . $config['db_port'] : '');
		if(@!$this->connection = $cmd($config['db_host'] . $port, $config['db_user'], $config['db_password']))
		{
			if(defined('RUN_GENERIC')) return FALSE;
			$this->base->error('Unable to connect to MySQL server.', E_DATABASE, mysql_errno() . ': ' . mysql_error());
		}
		if(@!mysql_select_db($config['db_name']))
		{
			if(defined('RUN_GENERIC')) return FALSE;
			$this->base->error('Unable to choose MySQL database.', E_DATABASE, mysql_errno() . ': ' . mysql_error());
		}
		$this->prefix = $config['db_prefix'];
		
		$this->execute('SET NAMES utf8', FALSE);
		$this->version();
		return TRUE;
	}

	function escape($input)
	{
		return mysql_real_escape_string($input, $this->connection);
	}

	function version()
	{
		if($this->version == NULL)
		{
			$this->version = mysql_get_server_info();
			$this->base->debug->sql($this->driver . ' Driver, Server Version ' . $this->version);
		}
		return $this->version;
	}

	function execute($query, $count = TRUE)
	{
		$sql_start_timer = microtime(TRUE);

		if(@!$this->result = mysql_query($query, $this->connection))
		{
			$this->base->error('Unable to execute a query.', E_DATABASE, mysql_errno() . ': ' . mysql_error() . '<p>' . $query . '</p>');
		}
		$sql_end_timer = microtime(TRUE) - $sql_start_timer;
		$this->exectime = (SMIT_DEBUG) ? $sql_end_timer : round($sql_end_timer, 2);
		
		if($count && SMIT_DEBUG)
		{
			$this->queries[] = array(
				'query' => $query,
				'time' => $this->exectime,
				'result' => $this->result
			);
			$this->base->debug->query($query);
		}
		if($count)
		{
			$this->query_count++;
		}

		// Reset Rows
		$this->rows = array();
		return $this->result;
	}

	function result($result = NULL, $type = 0)
	{
		switch($type)
		{
			default:
			case 0:
				$type = MYSQL_BOTH;
			break;
			case 1:
				$type = MYSQL_ASSOC;
			break;
			case 2:
				$type = MYSQL_NUM;
			break;
		}
		$arr = array();
		if($result == NULL)
		{
			if(count($this->rows) == 0)
			{
				while ($row = mysql_fetch_array($this->result, $type))
				{
					$this->rows[] = $row;
				}
			}
			return $this->rows;
		}
		else
		{
			while ($row = mysql_fetch_array($result, $type))
			{
				$arr[] = $row;
			}
			return $arr;
		}
	}

	function num_rows($result = NULL)
	{
		if($result == NULL)
		{
			return mysql_num_rows($this->result);
		}
		else
		{
			return mysql_num_rows($result);
		}
	}	

	function affected_rows()
	{
		return mysql_affected_rows($this->connection);
	}

	function buildquery()
	{
		/**
		 * SELECT, DELETE OR UPDATE?
		 **/
		if(count($this->q_select) > 0 && !$this->q_delete)
		{
			$this->query = 'SELECT ' . implode(', ', $this->q_select);
		}
		if($this->q_delete)
		{
			$this->query = 'DELETE ';
		}
		if($this->q_update != NULL)
		{
			$this->query = $this->q_update;
		}
		/**
		 * Now the rest
		 **/
		if(count($this->q_from) > 0)
		{
			$this->query .= ' FROM ' . implode(', ', $this->q_from);
		}
		if(count($this->q_where) > 0)
		{
			$this->query .= ' WHERE ';
			$keys = array_keys($this->q_where);
			$last_field = end($keys);
			
			foreach($this->q_where as $field => $options)
			{
				$logic = ($field != $last_field) ? ' AND ' : '';
				if(is_string($options[0]))
				{
					$this->query .= $this->l_delim . $field . $this->r_delim . ' ' . $options[1] . ' ' . $this->l_delim_val . $options[0] . $this->r_delim_val . $logic;
				}
				else
				{
					$this->query .= $this->l_delim . $field . $this->r_delim . ' ' . $options[1] . ' ' . $options[0] . $logic;
				}
			}
		}
		if(count($this->q_order) > 0)
		{
			$this->query .= ' ORDER BY ' . $this->l_delim . $this->q_order[0] . $this->r_delim . ' ' . $this->q_order[1];
		}
		if(count($this->q_limit) > 0)
		{
			$this->query .= ' LIMIT ' . $this->q_limit['range'] . ', ' . $this->q_limit['results'];
		}

		return $this->query;
	}

	function insert($table, $data)
	{
		if(strlen(trim($table)) == 0)
		{
			$this->base->error('An insert command was passed with an invalid table name.', E_DATABASE);
		}
		if(!is_array($data) && count($data) == 0)
		{
			$this->base->error('An insert command was passed without data.', E_DATABASE);
		}
		$build = 'INSERT INTO ' . $this->l_delim . $this->prefix . $table . $this->r_delim . ' ';
		$fields = '(';
		$values = '(';
		$last_field = (string) end(array_keys($data));
		$last_value = (string) end($data);

		foreach($data as $field => $value)
		{
			if($field != $last_field)
			{
				$fields .= $this->l_delim . $field . $this->r_delim . ', ';
			}
			else
			{
				$fields .= $this->l_delim . $field . $this->r_delim . ')';
			}
			
			if($value != $last_value)
			{
				$values .= $this->l_delim_val . $this->escape($value) . $this->r_delim_val . ', ';
			}
			else
			{
				$values .= $this->l_delim_val . $this->escape($value) . $this->r_delim_val . ')';
			}
		}
		$build .= $fields . ' VALUES ' . $values;
		$this->execute($build);
	}

	function update($table, $data)
	{
		if(strlen(trim($table)) == 0)
		{
			$this->base->error('An update command was passed with an invalid table name.', E_DATABASE);
		}
		if(!is_array($data) || count($data) == 0)
		{
			$this->base->error('An update command was passed without data.', E_DATABASE);
		}
		$build = 'UPDATE ' . $this->prefix . $table . ' SET ';
		$query = '';
		$keys = array_keys($data);
		$last_field = (string) end($keys);

		foreach($data as $field => $value)
		{
			if($field != $last_field)
			{
				$query .= $this->escape($field) . ' = \'' . $this->escape($value) . '\', ';
			}
			else
			{
				$query .= $this->escape($field) . ' = \'' . $this->escape($value) . '\'';
			}
		}
		$build .= $query;
		$this->q_update = $build;

		return $this;
	}
}
?>